package de.tum.wi.som.prio.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import de.tum.wi.som.Node;
import de.tum.wi.som.Project;
import de.tum.wi.som.prio.PriorityRule;
import de.tum.wi.som.util.PrioUtil;

/**
 * First Come First Serve Priority
 * Min(ES_il)
 * 
 * ES_il = early start time of the ith activity from the lth project
 * 
 * @author Enrico Pollok
 *
 */
public class FirstComeFirstServe implements PriorityRule {

	@Override
	public void prioritize(Project project) {
		project.calcProjectGraph();
		Node source = project.getSource();
		
		List<Node> scheduledNodes = new ArrayList<Node>();
		List<Node> remainingNodes = new ArrayList<Node>();
        remainingNodes.addAll(Arrays.asList(project.getNodes()));
		List<Node> accessibleNodes;
		
		Node dummyNode = new Node(0, new int[0]);
		Node candidateNode;
		
		while (!remainingNodes.isEmpty()){
			double earliestStart = Double.POSITIVE_INFINITY;
			accessibleNodes = PrioUtil.determineAccesibleNodes(scheduledNodes, source, remainingNodes);
            if (accessibleNodes.size() == 0) {
                System.err.println("No accessible nodes found in FirstComeFirstServe");
                return;
            }
			candidateNode = dummyNode;
			
			for (Node n : accessibleNodes){
				if (candidateNode == dummyNode || n.getEarliestStart() < earliestStart){
					candidateNode = n;
					earliestStart = n.getEarliestStart();
				}
			}
			
			remainingNodes.remove(candidateNode);
			scheduledNodes.add(candidateNode);
			
		}
		
		project.setNodes(scheduledNodes.toArray(new Node[scheduledNodes.size()]));
	}
	
	@Override
	public String toString(){
		return "FirstComeFirstServe";
	}
}
